#pragma once
#include <iostream>
#include "utility/index.hpp"
#include "request_access/index.hpp"
#include "data_access/index.hpp"
#include "components/index.hpp"
#include "actions.hpp"

using namespace std;
using namespace utility;

namespace components2 {
    class MaterialUseOrder : public components::EntityRequest {
    public:
        COMPONENT_INSTANCE_FUNCTION(MaterialUseOrder);

        MaterialUseOrder();

        any UpdateStatus();

        any Update2();

        any CancelReview();

    private:
        EntityData getMaterialUseOrderEntity(EntityData &dict);

        entity_access::EntityType *saleOrderEntity;
    };

    MaterialUseOrder::MaterialUseOrder() {
        SET_METHOD_ACTION(UpdateStatus);
        SET_METHOD_ACTION(Update2);
        SET_METHOD_ACTION(CancelReview);
        saleOrderEntity = entity_access::GetEntityType("SaleOrder");
    }

    std::any MaterialUseOrder::UpdateStatus() {
        EntityData dict = Request->RequestEntity.GetEntityData(Entity->Name);

        auto oldEntityData = SelectEntityByPrimaryKey(QueryRequest->PrimaryKeyValue);
        if (oldEntityData.Empty()) return Request->GetMessageMap("原料领用单不存在");

        auto msg = CompareVersion(dict, oldEntityData);
        if (!msg.empty()) return Request->GetMessageMap(msg);

        bool blSucceed = true;
        try {
            DataBase->BeginTransaction();

            blSucceed = Actions::UpdateStatusAndReview(shared_from_this(), nullptr, dict, 5);

            if (blSucceed)DataBase->CommitTransaction();
            else DataBase->RollbackTransaction();
        } catch (const std::exception &e) {
            DataBase->RollbackTransaction();
             throw MessageException(e.what(),"");
        }

        return GetSucceedMap(blSucceed);
    }

    any MaterialUseOrder::Update2() {
        auto dict = Request->RequestEntity.GetEntityData(Entity->Name);
        auto useOrder = getMaterialUseOrderEntity(dict);

        auto details = useOrder.GetEntityDataList("Details");
        if (details.empty()) return Request->GetMessageMap("领用原料商品明领取数量不能都为0");

        auto oldEntityData = SelectEntityByPrimaryKey(saleOrderEntity, dict.Get("SaleOrderId"));
        if (oldEntityData.Empty()) return Request->GetMessageMap("销售订单不存在");

        EntityData saleOrder;
        saleOrder["RowVersion"] = dict.Get("SaleRowVersion");

        auto msg = CompareVersion(saleOrder, oldEntityData);
        if (!msg.empty()) return Request->GetMessageMap(msg);

        Request->RequestEntity["MaterialUseOrder"] = useOrder;
        auto obj = Update();

        if (obj.ContainsKey("Succeed")) {
            EntityData updateEntityData;
            updateEntityData["UpdateDate"] = DateTime();
            updateEntityData["UpdateUser"] = Request->OperationUser;

            UpdateEntity(saleOrderEntity, GetQueryByPrimaryKey(saleOrderEntity, dict.Get("SaleOrderId")), updateEntityData);
        }

        return obj;
    }

    EntityData MaterialUseOrder::getMaterialUseOrderEntity(EntityData &dict) {
        EntityData data;

        data["UseOrderId"] = dict["UseOrderId"];
        data["UseEmployeeId"] = dict["UseEmployeeId"];
        data["UseDate"] = dict["UseDate"];
        data["Remark"] = dict["Remark"];
        data["Status"] = dict["Status"];
        data["RowVersion"] = dict["RowVersion"];

        auto details = dict.GetEntityDataList("Details");

        vector<EntityData> detailList;
        for (auto &d: details) {
            auto num = d.GetFloat("UseNum");
            if (num != 0) {
                EntityData detail;
                detail["Num"] = d["UseNum"];
                detail["DisplayIndex"] = d["DisplayIndex"];
                detail["MaterialProductId"] = d["MaterialProductId"];
                detailList.emplace_back(detail);
            }
        }

        data["Details"] = detailList;

        return data;
    }

    any MaterialUseOrder::CancelReview() {
        Actions::SetCancelReviewEntityData(shared_from_this());
        return UpdateStatus();
    }
}